#include <Arduino.h>
#include <WiFi.h>

#include <WiFiMulti.h>
#include <ArduinoJson.h>

#include <Wire.h>
#include "Protocentral_MAX30205.h"

String temp; //不要删除
String str1; //不要删除

void httpRequest();
String payloadJson; //报文
void get_gps_data();
void get_temp_data();
void get_distance_data();
void json_data_ser();

MAX30205 tempSensor;
float temperature;
#define SDA 21
#define SCL 22

WiFiMulti wifiMulti;                // 建立ESP8266WiFiMulti对象
const char *host = "192.168.0.55"; // 网络服务器地址
const int httpPort = 5000;          // http端口9990

const int TrigPin = 12; //设置发射脚位，对应ESP8266 D2
const int EchoPin = 13; //设置接收脚位，对应ESP8266 D1
float dis;             //浮点型数据类型（加小数点，提高精准度）

String GPS_rec;
String str_rec;
String UTC, timestamp;
String pos;

String ssid = "LAGRANGE";
String password = "abcdef..";

void setup()
{
    Serial.begin(115200);
    Serial2.begin(115200);
    // begin(int sdaPin, int sclPin, uint32_t frequency)
    Wire.begin(SDA, SCL);
    // Serial.println("start");

    while (!tempSensor.scanAvailableSensors())
    {
        Serial.println("Couldn't find the temperature sensor, please connect the sensor.");
        delay(3000);
    }
    tempSensor.begin();

    pinMode(TrigPin, OUTPUT);
    pinMode(EchoPin, INPUT);

    delay(100);
    // WiFi.mode(WIFI_STA); // 更换wifi模式
    // WiFi.setSleep(false);
    // WiFi.begin(ssid, password); // 连接wifi

    //通过addAp函数存储  WiFi名称       WiFi密码
    wifiMulti.addAP("LAGRANGE", "abcdef..");      // 这三条语句通过调用函数addAP来记录3个不同的WiFi网络信息。
    wifiMulti.addAP("PHICOMM", "skabcdef");       // 这3个WiFi网络名称分别是taichi-maker, taichi-maker2, taichi-maker3。
    wifiMulti.addAP("taichi-maker3", "13572468"); // 这3个网络的密码分别是123456789，87654321，13572468。
                                                  // 此处WiFi信息只是示例，请在使用时将需要连接的WiFi信息填入相应位置。
                                                  // 另外这里只存储了3个WiFi信息，您可以存储更多的WiFi信息在此处。
    int i = 0;
    while (wifiMulti.run() != WL_CONNECTED)
    {                // 此处的wifiMulti.run()是重点。通过wifiMulti.run()，NodeMCU将会在当前
        delay(1000); // 环境中搜索addAP函数所存储的WiFi。如果搜到多个存储的WiFi那么NodeMCU
        Serial.print(i++);
        Serial.print(' '); // 将会连接信号最强的那一个WiFi信号。
    }                      // 一旦连接WiFI成功，wifiMulti.run()将会返回“WL_CONNECTED”。这也是
                           // 此处while循环判断是否跳出循环的条件。
    // WiFi连接成功后将通过串口监视器输出连接成功信息
    Serial.println('\n');           // WiFi连接成功后
    Serial.print("Connected to ");  // NodeMCU将通过串口监视器输出。
    Serial.println(WiFi.SSID());    // 连接的WiFI名称
    Serial.print("IP address:\t");  // 以及
    Serial.println(WiFi.localIP()); // NodeMCU的IP地址
}

void loop()
{
    get_gps_data();
    get_temp_data();
    get_distance_data();
    json_data_ser();
    httpRequest();
    // Serial.println("loop");
    delay(500);
}

void get_gps_data()
{
    while (Serial2.available())
    {
        delay(10);
        // Serial.println("REC:");
        GPS_rec = Serial2.readStringUntil('*');
        Serial.println(GPS_rec);
        Serial2.readString();
        // temp = Serial2.readString();
    }

    if (GPS_rec.length() < 55)
    {
        UTC = GPS_rec.substring(GPS_rec.indexOf("$GNGNS,"), GPS_rec.indexOf(".00,"));
        pos = "no pos";
        // Serial.println("no pos");
    }
    else if (GPS_rec.length() >= 55)
    {
        // Serial.println("get pos");
        UTC = GPS_rec.substring(GPS_rec.indexOf("$GNGNS,"), GPS_rec.indexOf(".00,"));
        pos = GPS_rec.substring(GPS_rec.indexOf(".00,") + 4, GPS_rec.indexOf(".00,") + 26);
        // Serial.println(UTC);
        // Serial.println(pos);
    }
}

void get_temp_data()
{
    temperature = tempSensor.getTemperature();
    // delay(100);
}

void get_distance_data()
{
    digitalWrite(TrigPin, LOW); //用低高低电平发送脉冲给Trigpin引脚
    delayMicroseconds(2);       //微秒级延时
    digitalWrite(TrigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(TrigPin, LOW);
    dis = pulseIn(EchoPin, HIGH) / 58.0; //读取脉冲宽度，换算成厘米
    Serial.print(dis);                   //显示距离
    Serial.print("cm");
    Serial.println(); //回车
}

void json_data_ser()
{
    DynamicJsonDocument doc(1024);
    // dis = dis_sensor_data();
    payloadJson ="";
    doc["devID"] = String(WiFi.macAddress());
    doc["UTC"] = UTC;
    doc["distance"] = String(dis);
    doc["pos"] = pos;
    doc["temperature"] = String(temperature);
    // String jsonCode;
    serializeJson(doc, payloadJson);
}

void httpRequest()
{
    // 建立WiFi客户端对象，对象名称client
    WiFiClient client;
    // 根据jsonType参数建立不同类型JSON
    // String payloadJson = buildJson(dis_sensor_data());
    // 建立字符串，用于HTTP请求
    String httpRequest = String("GET /") + " HTTP/1.1\r\n" +
                         "Host: " + host + "\r\n" +
                         "Connection: close\r\n\r\n" + payloadJson;
    // 通过串口输出连接服务器名称以便查阅连接服务器的网址
    Serial.print("Connecting to ");
    Serial.print(host);
    if (client.connect(host, httpPort))
    {
        Serial.println(" Success!"); // 连接成功后串口输出“Success”信息

        client.print(httpRequest);           // 向服务器发送请求
        Serial.println("Sending request: "); // 通过串口输出HTTP请求信息内容以便查阅
        Serial.println(httpRequest);

        Serial.println("Web Server Response:"); // 通过串口监视输出服务器响应信息
        while (client.connected() || client.available())
        {
            if (client.available())
            {
                String line = client.readStringUntil('\n');
                Serial.println(line);
            }
        }
    }
    else
    { // 如果连接不成功则通过串口输出“连接失败”信息
        Serial.println("connect failed!");
    }
    client.stop();
    // client.close();                     // 断开与服务器的连接
    // Serial.print("Disconnected from "); // 并且通过串口输出断开连接信息
    // Serial.println(host);
}